----------------------------------------------------------------------------------
-- Company: 
-- Engineer: Ed Crampton
-- 
-- Create Date:    19:03:01 07/24/2011 
-- Design Name: 
-- Module Name:    tx_uart - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity tx_uart is
    Port ( 	TX_OUT : out  STD_LOGIC;
			TX_REG_8_BIT_IN : in  STD_LOGIC_VECTOR (7 downto 0);
			CLOCK_IN : in  STD_LOGIC;
			RESET_IN : in STD_LOGIC;
			WR_EN : in  STD_LOGIC;
			TICKSIGNAL_IN : in STD_LOGIC;
			WR_READY_OUT : out std_logic
			);
end tx_uart;

architecture Behavioral of tx_uart is
signal tick_sig : std_logic := '0';
signal cnt : std_logic_vector(7 downto 0) := (others => '0');
signal tx_reg	: std_logic_vector(7 downto 0) := (others => '0');
signal cnt_en : std_logic := '0';
signal reset_cnt : std_logic := '0';
signal bit_cnt : std_logic_vector(3 downto 0) := (others => '0');
signal wr_ready_sig : std_logic;
signal wr_delay : std_logic := '0';

begin
tick_sig <= TICKSIGNAL_IN;


--read in tx data
tx_data : process(CLOCK_IN)
begin
	if(rising_edge(CLOCK_IN)) then
		tx_reg <= TX_REG_8_BIT_IN;
	end if;
end process;

WR_READY_OUT <= '0' when (WR_EN = '1' or wr_delay = '1') else wr_ready_sig;

tx_process : process(CLOCK_IN)
begin

	if(rising_edge(CLOCK_IN)) then
		reset_cnt <= '0';
		wr_delay <= WR_EN; 
		wr_ready_sig <= '0';
		
		if(WR_EN = '1' and wr_ready_sig ='1') then
			cnt_en <= '1';
			bit_cnt <= x"1";
		end if;
		
		case bit_cnt is
			when x"1" =>
				TX_OUT <= '0'; --start bit
			when x"2" =>
				TX_OUT <= tx_reg(0);
			when x"3" =>
				TX_OUT <= tx_reg(1);
			when x"4" =>
				TX_OUT <= tx_reg(2);
			when x"5" =>
				TX_OUT <= tx_reg(3);
			when x"6" =>
				TX_OUT <= tx_reg(4);
			when x"7" =>
				TX_OUT <= tx_reg(5);		
			when x"8" =>
				TX_OUT <= tx_reg(6);
			when x"9" =>
				TX_OUT <= tx_reg(7);
			when x"A" =>
				TX_OUT <= '1';
			when x"B" =>
				reset_cnt <= '1';
				cnt_en <= '0';
				TX_OUT <= '1';
			when others =>
				TX_OUT <= '1';
				wr_ready_sig <= '1';
		end case;

		if(tick_sig = '1' and cnt_en = '1') then
				cnt <= std_logic_vector( unsigned(cnt) + 1 );
		end if;
			
		if(cnt = x"10" and cnt_en = '1') then
			cnt <= (others => '0');
			bit_cnt <= std_logic_vector( unsigned(bit_cnt) + 1 );
		end if;
		
		if(reset_cnt = '1') then
			cnt <= (others => '0');
			bit_cnt <= (others => '0');
		end if;
	end if;
end process;

end Behavioral;

